home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_2 / mach.cod < prev    next >
Text File  |  1991-04-12  |  11KB  |  257 lines

  1. Article 1500 of comp.sys.handhelds:
  2. Path: en.ecn.purdue.edu!pur-ee!mentor.cc.purdue.edu!purdue!bu.edu!snorkelwacker!bloom-beacon!bloom-beacon!athena.mit.edu!chekmate
  3. From: chekmate@athena.mit.edu (Adam Kao)
  4. Newsgroups: comp.sys.handhelds
  5. Subject: routines to enter HP48 machine language programs
  6. Message-ID: <1990Mar14.183918.15326@athena.mit.edu>
  7. Date: 14 Mar 90 18:39:18 GMT
  8. Sender: news@athena.mit.edu (News system)
  9. Reply-To: chekmate@athena.mit.edu (Adam Kao)
  10. Organization: Massachusetts Institute of Technology
  11. Lines: 242
  12.  
  13. =====================================================================
  14.  
  15. NOTE1: This is being posted for me by a friend, since I have no usenet
  16.        or email access right now.  If you want to respond to something
  17.        in this article, you'll have to use (gasp) regular mail.  Hurry
  18.        up while it's still $.25.
  19.  
  20.  
  21. NOTE2: All of the SYSEVAL addresses contained in these routines are
  22.        valid for the HP48SX Version A only.
  23.  
  24.  
  25. In a previous article, Alonzo Gariepy posted information on using the 
  26. memory scanning utility built into the HP48 to enter machine language
  27. programs.  The three routines below provide a similar capability, without
  28. having to use the memory scanner.  They are adapted from routines that
  29. I have been using on the HP28S.  The main routine, STR->OBJ, takes a string
  30. of hex digits and returns the object whose representation is those digits.
  31. This can be used to create just about anything you want, including 
  32. machine language routines.  Some examples are shown below.
  33.  
  34. I have provided a little documentation on the SYSEVALs used, but I am
  35. assuming some familiarity with how HP28/HP48 objects are represented, 
  36. and with the machine code of the Saturn CPU.
  37.  
  38.  
  39. Dave Kaffine
  40. 33 Agassiz Ave.
  41. Belmont, MA  02178
  42. (617) 484-3393
  43.  
  44.  
  45. ==================================================================
  46.  
  47.  
  48. RVRS  [2022h]  75.5 bytes    ; Reverses the characters in a string
  49.  
  50. <<   -> s 
  51.      << ""                           ; Start with empty string on stack
  52.         s SIZE 1 FOR x               ; Loop from end to beginning
  53.            s x x SUB +               ;  and add each character
  54.         -1 STEP
  55.      >>
  56. >>
  57.  
  58.  
  59. SYSRCL  [6E80h]  54 bytes
  60.                             ; Given an address (as a binary integer), 
  61.                             ;   puts the object at that address
  62.                             ;   on the stack without evaluating it.
  63.                             ;   Can also be used with other data types - see
  64.                             ;   detailed description below.
  65.                             ;   NOTE: For the most part, this should not be
  66.                             ;         dangerous until you try to do something
  67.                             ;         with the recalled item.
  68.  
  69. << #4003h SYSEVAL              ; <2h>  (short integer - prolog 02911)
  70.    #56B6h SYSEVAL              ; described below
  71.    DROP                        ; DROPs boolean value
  72. >>
  73.  
  74. The routine at 056B6 works as follows:
  75.  
  76.     2:  COMP    ==>     2: Object     or    
  77.     1:  <Nh>            1: TRUE              1: FALSE
  78.  
  79. The routine ignores the type of the object in level 2.  It assumes that
  80. COMP consists of a series of objects, one after another (e.g. a list).
  81. Each list object either consists of a known prolog and the associated data for
  82. that object type, or is a 5-nibble address that is assumed to point to
  83. some data object.  The routine locates the Nth object and puts it on the
  84. stack as follows: If the Nth object in the list starts with a prolog, a
  85. pointer to the object within the list is put on the stack.  If the Nth
  86. object in the list is an address pointing to an actual object, that address
  87. is copied to the stack.  If N is out of range, a FALSE value is put on the
  88. stack, otherwise a TRUE value is put on the stack (FALSE and TRUE are
  89. special objects used by internal routines.  They are displayed as 
  90. "External").
  91.  
  92. Some notes:  This routine works well with lists, but since the prolog of
  93. the level 2 object is not checked, it gives interesting results with other
  94. data types.  For example, with a binary integer argument:
  95.  
  96.              Binary integer                      <-- Increasing addresses
  97.            MSB-------------LSB   length  prolog (ignored)
  98.            b bbbbb bbbbb aaaaa   00015   02A4E   <-- Level 2
  99.                           \       \      
  100.                            \       \-- 1st object
  101.                             \
  102.                              \-- 2nd object (interpreted as an address
  103.                                   unless aaaaa = known prolog)
  104.  
  105. So, if the level one argument has the value 2 (as in the SYSRCL routine),
  106. and the level 2 argument is # aaaaah, the address aaaaa will be put on the
  107. stack, which is the same as RCLing the object located at address aaaaa.
  108.  
  109. (BTW,  #18CEAh SYSEVAL   converts a real number to a short integer type, and
  110.        #18DBFh SYSEVAL   converts the other way)
  111.  
  112.  
  113. Example using SYSRCL:
  114.  
  115.        #1AB67h  SYSRCL         ==>              +      
  116.  
  117.  
  118.  
  119.  
  120. STR->OBJ  [C2h]  169 bytes 
  121.                       ;  STRing to OBJect :  This takes a string that is
  122.                       ;    the sequence of nibbles that represent an object
  123.                       ;    you want to create, and translates it into
  124.                       ;    a new string that, when stored in memory,
  125.                       ;    contains a nibble sequence that matches the digits
  126.                       ;    in the original string.  It then uses SYSRCL
  127.                       ;    (see explanation of how that works above,
  128.                       ;    and see additional notes below) to bring the
  129.                       ;    desired object to the stack.
  130.  
  131. << RCLF SWAP 64 STWS
  132.    -> s
  133.        << ""                          ; Start with empty string
  134.           1 s SIZE FOR x              ; Loop through string by pairs of
  135.               "#"                     ;   characters
  136.               s x DUP 1 + SUB         ; Get pair of digits (single digit
  137.               RVRS                    ;   at end handled correctly)
  138.               + "h" + OBJ->           ; Swap order, make binary integer
  139.               B->R CHR +              ;  make into character and append
  140.           2 STEP                      ; Loop by 2
  141.        >>
  142.     'obj' STO                         ; Store result so it won't move
  143.     obj SYSRCL                        ; RCL desired object to stack
  144.     NEWOB                             ; Make it a private copy
  145.     SWAP STOF                         ; Clean up
  146. >>
  147.  
  148. More notes about the routine at 056B6:
  149.  
  150. This time we're calling it with a "string" as the composite type.
  151. Let's assume the string starts at address sssss.
  152.                                           
  153.       String (constructed to look like a program)
  154.                            5th char    1st 
  155.                              |           |  length    String prolog
  156.       ... xx xx xx xx xx xx 23 61 E0 2D 9D  LLLLL     02A2C : sssss
  157.                                     \       \
  158.                                      \       \-- Object 1
  159.                                       \
  160.                                        \-- Object 2 - starts with 02D9D,
  161.                                            the prolog for a program, so
  162.                                            object consists of entire
  163.                                            program.
  164.  
  165. SYSRCL  will RCL the program by placing the address (sssss+10) on the
  166. stack.  Unfortunately, this address is not a 'good' address, since it
  167. doesn't point to a 'real' object, it points inside of an object that is not
  168. normally considered a composite type.  This means that if the string gets
  169. moved (e.g. as a result of garbage collection), the address on the stack
  170. will NOT be updated properly!!  That is the reason STR->P stores the
  171. string in the global variable obj first (it must be a global variable - local
  172. variables do not make copies of their contents) so its position won't be
  173. affected by garbage collection.  After calling SYSRCL, NEWOB is used to 
  174. make a separate copy of the item on the stack, so that the string it was 
  175. derived from can be deleted safely.  Note that this program does not depend
  176. upon being in the HOME directory - it does create one global variable called
  177. 'obj', but it doesn't matter where in memory 'obj' gets stored.
  178.  
  179.  
  180.  
  181. Here are some examples of the above routines in use:
  182.  
  183.  
  184. Start with a simple, relatively safe example:
  185.  
  186.       Keystrokes                            Results
  187.     -------------------------------------------------------
  188.     "D9D20E163276BA193632B2130"       ==>   "..."
  189.     DUP  BYTES                        ==>   #A0BDh 30
  190.     DROP2                             ==>   "..."
  191.     STR->OBJ                          ==>   <<  +  >>
  192.  
  193. Try it out - see if it's real.
  194.  
  195.     3 5 ROT                           ==>   3 5 << + >>
  196.     EVAL                              ==>   8
  197.  
  198. !!!
  199.           
  200.  
  201.  
  202. Now for a more complicated example:
  203.  
  204. PEEK  [A1BCh]  50 bytes
  205.  
  206.       1: # aaaaah      ==>       1: # ddddddddddddddddh
  207.  
  208.       dddddddddddddddd is 16 nibbles of data from address aaaaa.
  209.       The least significant nibble of data is from address aaaaa,
  210.       the most significant is from aaaaa + F.
  211.  
  212.  
  213.     D9D20                       ; Begin program
  214.     E1632                       ; << 
  215.       BB691                     ;  B->R  - make sure arg is binary integer,
  216.       B9691                     ;  R->B  - and force new storage for it.
  217.       CCD20                     ;  In-line code prolog
  218.         03000                   ;  48 nibbles (includes these 5 nibbles)
  219.           147      C=DAT1  A    ;    C -> level 1 object
  220.           137      CD1EX        ;    D1 -> level 1 object, 
  221.           06       RSTK=C       ;      save old D1 on stack
  222.           179      D1=D1+  10   ;    D1 -> data of lvl 1 binary integer
  223.           147      C=DAT1  A    ;    C = 5 nibs from binary (addr to PEEK)
  224.           137      CD1EX        ;    D1 = PEEK addr, C -> lvl 1 data area
  225.           15BF     A=DAT1  16   ;    peek 16 nibs into A
  226.           137      CD1EX        ;    D1 -> lvl 1 data area
  227.           159F     DAT1=A  16   ;    Replace binary data with peeked data
  228.           07       C=RSTK       ;    Get old D1
  229.           137      CD1EX        ;    and restore
  230.           142      A=DAT0  A    ;    End every
  231.           164      D0=D0+  5    ;      routine
  232.           808C     PC=(A)       ;        this way.
  233.     93632                       ; >>
  234.     B2130                       ; End program
  235.  
  236. To enter this, do the following:
  237.     "D9D20E1632BB691B                    ; Direct copy of sequence of
  238.      9691CCD200300014                    ; nibbles above (NOTE: Do not
  239.      7137061791471371                    ; put any extra characters in - 
  240.      5BF137159F071371                    ; there are no spaces or newline
  241.      42164808C93632B2                    ; characters)
  242.      130"
  243.      DUP  BYTES                          ; ==>  #1412h, 88
  244.      DROP2
  245.      STR->OBJ                            ; ==>  << B->R  R->B  Code >>
  246.      'PEEK'    STO                       ;
  247.      'PEEK'    BYTES                     ; ==>  #A1BCh, 50
  248.  
  249.  
  250. Now test it out:
  251.      #0  PEEK                ==>         # 8001FDAD801B9632h
  252.  
  253.  
  254. That's all for now.  Enjoy!
  255.  
  256.  
  257.